*********************************************************
* Analysis Part 1: Tables 1-6, Figure 2
* 
* Topic: The Value of Ratings: Evidence from their Introduction in Securities Markets
* Authors: Asaf Bernstein, Carola Frydman, Eric Hilt
* 
* Code last updated: 5/23/25
* 
*************************************************************

*************************************************************
* I. Initial Code Settings/Directories
*************************************************************

clear all
* Set to folder of where do file is saved. Change if necessary.
cd "`=substr(c(current_do), 1, indexnot(c(current_do), "/", -1))'"

log using "Part1_Surprises_Log.txt", text replace

*************************************************************
* II. Load in data
*************************************************************

use "BondTransactionsAndRatingsWithSurprises.dta", clear

*************************************************************
* III. Analysis/output
*************************************************************

*************************************************************
* Table 1
*************************************************************

preserve

    replace avg_income = avg_income/1000
    replace YTM_Last_wis = YTM_Last_wis*100
    local prod_vars `"factor_of_safety avg_income rank_in_moodys_1909 YTM_Last_wis"'
    foreach x of local prod_vars {
	   bys rating_num: egen byrat_`x' = mean(`x')
    }	

    tabdisp rating_num, cell(byrat_*)

restore

*************************************************************
* Table 2
*************************************************************


corr median_rating mnfactor_of_safety mnavg_income mninterest_per_mile mnduration mnPreMean_Spread_pct mnPreMean_YTM_Last


*************************************************************
* Table 3
*************************************************************

sum mean_issuer_PM_YTM_Last if PreMeanYTM_Last_Qs==1, d
sum mean_issuer_PM_YTM_Last if PreMeanYTM_Last_Qs==2, d
sum mean_issuer_PM_YTM_Last if PreMeanYTM_Last_Qs==3, d
sum mean_issuer_PM_YTM_Last if PreMeanYTM_Last_Qs==4, d

tab median_rating if PreMeanYTM_Last_Qs==1
tab median_rating if PreMeanYTM_Last_Qs==2
tab median_rating if PreMeanYTM_Last_Qs==3
tab median_rating if PreMeanYTM_Last_Qs==4

sum median_rating if PreMeanYTM_Last_Qs==1, d
sum median_rating if PreMeanYTM_Last_Qs==2, d
sum median_rating if PreMeanYTM_Last_Qs==3, d
sum median_rating if PreMeanYTM_Last_Qs==4, d


*************************************************************
* Table 4
*************************************************************

global file_name_new_v1 "T4"
global tbl_title "Table 4. Effect of Ratings Surprises on Yields"
sort id_issue date_bin

*Column 1

    reghdfe yield neg_post if (wk_since<0 | wk_since>=26), absorb(id_issue c.date_bin##i.rating_num date_bin) vce(cluster id_issue)	
	est store t4c1

*Column 2	

    reghdfe yield neg_weeks_post neg_weeks, absorb(id_issue c.date_bin##i.rating_num date_bin) vce(cluster id_issue)
	est store t4c2
    *Implied 12-mo ATE
    lincom neg_weeks_post*52
    
*Column 3

    reghdfe yield neg_weeks_since, absorb(id_issue c.date_bin##i.rating_num date_bin) vce(cluster id_issue)
	est store t4c3
    *Implied 12-mo ATE
    lincom neg_weeks_since*52
    
*Column 4

    reghdfe yield neg_weeks_since, absorb(id_issue c.date_bin##i.rating_num date_bin i.mat_yr_gp1##c.date_bin) vce(cluster id_issue)
	est store t4c4
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 5	

    *Switch to bond-level surprise
    cap drop temp_var
    gen temp_var = neg_weeks_since
    replace neg_weeks_since = weeks_since_negsurp_issue
    *Estimate regression
    reghdfe yield neg_weeks_since, absorb(id_issue c.date_bin##i.rating_num date_bin) vce(cluster id_issue)
	est store t4c5
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 6	

    reghdfe yield neg_weeks_since, absorb(id_issue i.id_issuer_1##c.date_bin c.date_bin##i.rating_num date_bin) vce(cluster id_issue)
	est store t4c6
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 7
	
    reghdfe yield neg_weeks_since, absorb(id_issue i.id_issuer_1##c.date_bin c.date_bin##i.rating_num date_bin i.mat_yr_gp1##c.date_bin) vce(cluster id_issue)	
	est store t4c7
    *Implied 12-mo ATE
    lincom neg_weeks_since*52
    
*Table of results
	
    esttab t4c* using "$file_name_new_v1.rtf", replace compress nogaps se ///
	   drop(*cons*) ///
	   title($tbl_title) ///
	   addnote("") ///
	   label interaction(" X ") starlevels("{\super *}" 0.10 "{\super **}" 0.05 "{\super ***}" 0.01)

    tempname handle4
    rtfappend `handle4' using "$file_name_new_v1.rtf", replace
    file write `handle4' "\page"
    rtfclose `handle4'


*************************************************************
* Table 5
*************************************************************

global file_name_new_v1 "T5"
global tbl_title "Table 5. Effect of Surprises, Controlling for Rating Predictors"

*Switch back to issuer-level surprise

    replace neg_weeks_since = temp_var	

*Column 1

    reghdfe yield neg_weeks_since, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)
	est store t5c1
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 2

    reghdfe yield neg_weeks_since yield_wks, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)
	est store t5c2
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 3   	

    reghdfe yield neg_weeks_since fsafety_wks, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)
	est store t5c3
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 4

    reghdfe yield neg_weeks_since fsafety_wks avginc_wks intrst_wks, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue) /*old*/
	est store t5c4
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 5

    reghdfe yield neg_weeks_since fsafety_wks avginc_wks intrst_wks duration_wks, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue) /*old*/
	est store t5c5
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 6

    reghdfe yield neg_weeks_since yield_wks fsafety_wks avginc_wks intrst_wks duration_wks spread_wks, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue) /*old*/
	est store t5c6
    *Implied 12-mo ATE
    lincom neg_weeks_since*52

*Column 7

    ivreghdfe yield (neg_weeks_since = yield_wks fsafety_wks avginc_wks intrst_wks duration_wks spread_wks), absorb(id_issue date_bin c.date_bin##i.rating_num) cluster(id_issue) ffirst
	est store t5c7
    *Implied 12-mo ATE
    lincom neg_weeks_since*52
    *F-stat
    matrix first_stage = e(widstat)
	local first_f = first_stage[1,1]
	display "Kleibergen-Paap F, First Stage: " `first_f'
    
*Table of results

    esttab t5* using "$file_name_new_v1.rtf", replace compress nogaps se ///
	   drop(*cons*) ///
	   title($tbl_title) ///
	   addnote("") ///
	   label interaction(" X ") starlevels("{\super *}" 0.10 "{\super **}" 0.05 "{\super ***}" 0.01)

    tempname handle4
    rtfappend `handle4' using "$file_name_new_v1.rtf", replace
    file write `handle4' "\page"
    rtfclose `handle4'

*************************************************************
* Table 6
*************************************************************

global file_name_new_v1 "T6"
global tbl_title "Table 6. Heterogeneity in Effect of Ratings Surprises on Yields"
	
*Column 1

    reghdfe yield neg_weeks_since neg_wks_m_undw wks_m_undw, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)		
	est store t6c1
	
*Column 2

    reghdfe yield neg_weeks_since if numuw_top10>=3, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)		
	est store t6c2

*Column 3

    reghdfe yield neg_weeks_since if (numuw_top10==1 | numuw_top10==2), absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)		
	est store t6c3

*Column 4

    reghdfe yield neg_weeks_since if numuw_top10==0, absorb(id_issue date_bin c.date_bin##i.rating_num) vce(cluster id_issue)		
	est store t6c4

*Table of results

    esttab t6c* using "$file_name_new_v1.rtf", replace compress nogaps se ///
	   drop(*cons*) ///
	   title($tbl_title) ///
	   addnote("") ///
	   label interaction(" X ") starlevels("{\super *}" 0.10 "{\super **}" 0.05 "{\super ***}" 0.01)

    tempname handle4
    rtfappend `handle4' using "$file_name_new_v1.rtf", replace
    file write `handle4' "\page"
    rtfclose `handle4'

*************************************************************
* Figure 2
*************************************************************

qui reghdfe yield bd_date_dum_*, absorb(date_bin id_issue c.date_bin##i.rating_num) vce(cluster id_issue) 
coefplot,  xtitle("" ,size(tiny)) plotregion(margin(0)) transform(* = min(max(@,-40),40)) ysc(r(-40 -30 -20 -10 0 10 20 30 40) noextend) ///
	ylabel(-40 -30 -20 -10 0 10 20 30 40) addplot(pci -40 48 40 48, lcolor(red) lpattern(solid) || pci -40 38 40 38, lcolor(navy) lpattern(shortdash) || pci -40 12 40 12, lcolor(navy) lpattern(shortdash) || pci 0 0 0 96, lcolor(gs3)) ///
	ylabel(,nogrid) lcolor(black) ciopts(color(gray)) msize(tiny) mlcolor(black) mcolor(black) keep(bd_date_dum_*) xlabel(, labgap(0) noticks labsize(small) angle(90)) ///
	vertical ytitle("Yield (bps)") title("", size(small)) recast(connected) graphregion(color(white)) text(35 58 "{bf:Ratings Released}", color(red) size(small)) text(35 24 "Ratings Constructed", color(navy) size(small))
	
graph export "Fig2.png", replace

log close












